What is Object-Oriented Software?
by Terry Montlick
Software Design
Consultants
Copyright 1995-1999 by Software Design Consultants, LLC. All rights
reserved.
The Heart of the Matter - The "Black Box"
Object-oriented
software is all about objects. An object is a "black
box" which receives and sends messages. A black
box actually contains code (sequences of computer instructions)
and data (information which the instructions operates on). Traditionally,
code and data have been kept apart. For example, in the C language, units
of code are called functions, while units of data are called
structures. Functions and structures are not formally connected
in C. A C function can operate on more than one type of structure, and
more than one function can operate on the same structure.
Not so for object-oriented
software! In o-o (object-oriented) programming, code and data
are merged into a single indivisible thing -- an object. This has some
big advantages, as you'll see in a moment. But first, here is why SDC
developed the "black box" metaphor for an object. A primary
rule of object-oriented programming is this: as the user of an object,
you should never need to peek inside the box!
An object
Why shouldn't you
need to look inside an object? For one thing, all communication to it
is done via messages. The object which a message is sent
to is called the receiver of the message. Messages define
the interface to the object. Everything an object can do is represented
by its message interface. So you shouldn't have to know anything about
what is in the black box in order to use it.
And not looking inside
the object's black box doesn't tempt you to directly modify that object.
If you did, you would be tampering with the details of how the object
works. Suppose the person who programmed the object in the first place
decided later on to change some of these details? Then you would be in
trouble. Your software would no longer work correctly! But so long as
you just deal with objects as black boxes via their messages, the software
is guaranteed to work. Providing access to an object only through its
messages, while keeping the details private is called information
hiding. An equivalent buzzword is encapsulation.
Why all this concern
for being able to change software? Because experience has taught us that
software changes. A popular adage is that "software is not written,
it is re-written". And some of the costliest mistakes in computer
history have come from software that breaks when someone tries to change
it.
Classes
How
are objects defined? An object is defined via its class,
which determines everything about an object. Objects are individual instances
of a class. For example, you may create an object call Spot from class
Dog. The Dog class defines what it is to be a Dog object, and
all the "dog-related" messages a Dog object can act upon. All
object-oriented languages have some means, usually called a factory,
to "manufacture" object instances from a class definition.
Spot
You can make more
than one object of this class, and call them Spot, Fido, Rover, etc. The
Dog class defines messages that the Dog objects understand, such as "bark",
"fetch", and "roll-over".
You may also hear
the term method used. A method is simply the action that
a message carries out. It is the code, which gets executed when the message
is sent to a particular object.
Arguments are often
supplied as part of a message. For example, the "fetch" message
might contain an argument that says what to fetch, like "the-stick".
Or the "roll-over" message could contain one argument to say
how fast, and a second argument to say how many times.
Some Real Life Examples
If
you wanted to add two numbers, say, 1 and 2, in an ordinary, non-object-oriented
computer language like C (don't worry -- you don't need to know any C
to follow this), you might write this:
a = 1;
b = 2;
c = a + b;
This says,
"Take
a, which has the value 1, and b, which has the value
2, and add them together using the C language's built-in addition capability.
Take the result, 3, and place it into the variable called c."
Now, here's
the same thing expressed in Smalltalk, which is a pure object-oriented
language:
a := 1.
b := 2.
c := a + b.
Wait a minute.
Except for some minor notational differences, this looks exactly the same!
Okay, it is the same, but the meaning is dramatically different.
In Smalltalk,
this says,
"Take
the object a, which has the value 1, and send it the message
"+", which included the argument b, which,
in turn, has the value 2. Object a, receive this message and
perform the action requested, which is to add the value of the argument
to yourself. Create a new object, give this the result, 3, and assign
this object to c."
Hmm. This
seems like a far more complicated way of accomplishing exactly the same
thing! So why bother?
The reason
is that objects greatly simplify matters when the data get more complex.
Suppose you wanted a data type called list, which is a list of names.
In C, list would be defined as a structure.
struct list {
<definition
of list structure data here>
};
list a, b, c;
a = "John Jones";
b = "Suzy Smith";
Let's try
to add these new a and b in the C language:
c = a + b;
Guess what?
This doesn't work. The C compiler will generate an error when it tries
to compile this because it doesn't know what to do with a and
b. C compilers just know how to add numbers. Period. But a
and b are not numbers. One can do the same thing in Smalltalk,
but this time, list is made a class, which is a subclass of the
built-in Smalltalk class called "String":
a := List fromString: 'John Jones'.
b := List fromString: 'Suzy Smith'.
c := a + b.
The first
two lines simply create List objects a and b from the
given strings. This now works, because the list class was created with
a method which specifically "knows" how to handle the message
"+". For example, it might simply combine the argument with
its own object by sticking them together with a comma separating them
(this is done with a single line of Smalltalk). So c will have
the new value:
'John Jones, Suzy Smith'
Here's another
example of a "+" message using more interesting objects. Click
a, b, and c in turn to find out what they are (you'll need a WWW browser
with support for "aiff" sounds):
c
= a + b;
Using Non-Object-Oriented Languages
It's
also possible to use objects and messages in plain old non-object-oriented
languages. This is done via function calls, which look ordinary, but which
have object-oriented machinery behind them. Among other things, this allows
sophisticated client-server software to run "transparently"
from within ordinary programming languages.
Suppose
you added a "plus" function to a C program:
int plus(int arg1, int arg2)
{return (arg1 + arg2); }
This hasn't
really bought you anything yet. But suppose that instead of doing the
addition on your own computer, you automatically sent it to a server computer
to be performed:
int plus(int arg1, int arg2)
{ return server_plus(arg1, arg2); }
The function
server_plus() in turn creates
a message containing arg1 and arg2, and sends this message,
via a network, to a special object which sits on a server computer. This
object executes the "plus" function and sends the result back
to you. It's object-oriented computing via a back-door approach!
This example
is not very fancy, and, of course, it's easier to simply add two numbers
directly. But as the musical example illustrated, there's no limit to
the complexity of an object. A single object can include entire databases,
with millions of pieces of information. In fact, such database objects
are common in client-server software.
This also
illustrates the flexibility of the object-oriented approach. In the usage
just described, the object is very different from the earlier "a
+ b" example. Here, it receives two arguments, namely, the
two objects that it is supposed to add. Previously, in the Smalltalk example,
the object that was receiving a message was the first object, a.
But in a client-server environment, the addition is not done locally,
on the client machine, but remotely, on a server machine. The server machine
contains the object that the message is sent to, and since it doesn't
know anything about the first argument, you have to send both
arguments.
Inheritance
If
there is already a class which can respond to a bunch of different messages,
what if you wanted to make a new, similar class which adds just a couple
of more messages? Why have to re-write the entire class?
Of course,
in any good object-oriented language, you don't. All you need to do is
create a subclass (or derived class,
in C++ terminology) of the original class. This new class inherits
all the existing messages, and therefore, all the behavior of the original
class. The original class is called the parent class,
or superclass, of the new class. Some more jargon --
a subclass is said to be a specialization of its superclass,
and the conversely a superclass a generalization of its
subclasses.
Inheritance
also promotes reuse. You don't have to start from scratch
when you write a new program. You can simply reuse an existing repertoire
of classes that have behaviors similar to what you need in the new program.
For example,
after creating the class Dog, you might make a subclass called
Wolf, which defines some wolf-specific messages, such as hunt.
Or it might make more sense to define a common class called Canis,
of which both Dog and Wolf are subclasses.
Much of
the art of o-o programming is determining the best way to divide a program
into an economical set of classes. In addition to speeding development
time, proper class construction and reuse results in far fewer lines of
code, which translates to less bugs and lower maintenance costs.
Object-Oriented Languages
There
are almost two dozen major object-oriented programming languages in use
today. But the leading commercial o-o languages are far fewer
in number. These are:
C++
C++ is an
object-oriented version of C. It is compatible with C (it is actually
a superset), so that existing C code can be incorporated into C++ programs.
C++ programs are fast and efficient, qualities which helped make C an
extremely popular programming language. It sacrifices some flexibility
in order to remain efficient, however. C++ uses compile-time binding,
which means that the programmer must specify the specific class of an
object, or at the very least, the most general class that an object can
belong to. This makes for high run-time efficiency and small code size,
but it trades off some of the power to reuse classes.
C++ has
become so popular that most new C compilers are actually C/C++ compilers.
However, to take full advantage of object-oriented programming, one must
program (and think!) in C++, not C. This can often be a major problem
for experienced C programmers. Many programmers think they are coding
in C++, but instead are only using a small part of the language's object-oriented
power.
Smalltalk
Smalltalk
is a pure object-oriented language. While C++ makes some practical compromises
to ensure fast execution and small code size, Smalltalk makes none. It
uses run-time binding, which means that nothing about the type
of an object need be known before a Smalltalk program is run.
Smalltalk
programs are considered by most to be significantly faster to develop
than C++ programs. A rich class library that can be easily reused via
inheritance is one reason for this. Another reason is Smalltalk's dynamic
development environment. It is not explicitly compiled, like C++. This
makes the development process more fluid, so that "what if"
scenarios can be easily tried out, and classes definitions easily refined.
But being purely object-oriented, programmers cannot simply put their
toes in the o-o waters, as with C++. For this reason, Smalltalk generally
takes longer to master than C++. But most of this time is actually spent
learning object-oriented methodology and techniques, rather than details
of a particular programming language. In fact, Smalltalk is syntactically
very simple, much more so than either C or C++.
Unlike C++,
which has become standardized, The Smalltalk language differs somewhat
from one implementation to another. The most popular commercial "dialects"
of Smalltalk are:
- VisualWorks
from ParcPlace-Digitalk, Inc.
- Smalltalk/V
and Visual Smalltalk from ParcPlace-Digitalk Inc.
- VisualAge
from IBM
VisualWorks
VisualWorks
is arguably the most powerful of Smalltalks. VisualWorks was developed
by ParcPlace, which grew out of the original Xerox PARC project that invented
the Smalltalk language. VisualWorks is platform-independent,
so that an application written under one operating system, say, Microsoft
Windows, can work without any modification on any of a wide range of platform
supported by ParcPlace, from Sun Solaris to Macintosh. VisualWorks also
features a GUI (Graphic User Interface) builder that is well-integrated
into the product.
Smalltalk/V and Visual Smalltalk
Digitalk's
versions of Smalltalk are somewhat smaller and simpler, and are specifically
tailored to IBM compatible PCs. A Macintosh version was available, but
support has since been abandoned. This does not bode well for Digitalk
cross-platform efforts. Digitalk has a separate GUI builder, called PARTS
Workbench (bundled with Visual Smalltalk), which allows quick construct
of an application.
ParcPlace
and Digitalk were merged into a single company, ParcPlace-Digitalk, Inc.
The future of the Digitalk product line is uncertain, and it may just
be spun off back into a separate company.
VisualAge
IBM's version
of Smalltalk, VisualAge, is comparable to Smalltalk/V with PARTS. Both
of these Smalltalks allow programmers to readily exploit machine-specific
features, at the expense of some portability. IBM has adapted existing
industry standards for such things as file management and screen graphics.
When IBM talks, people listen, and IBM has made a substantial commitment
to Smalltalk.
Java
Java is
the latest, flashiest object-oriented language. It has taken the software
world by storm due to its close ties with the Internet and Web browsers.
It is designed as a portable language that can run on any web-enabled
computer via that computer's Web browser. As such, it offers great promise
as the standard Internet and Intranet programming language.
Java is
a curious mixture of C++ and Smalltalk. It has the syntax of C++, making
it easy (or difficult) to learn, depending on your experience. But it
has improved on C++ in some important areas. For one thing, it has no
pointers, low-level programming constructs that make for error-prone
programs. Like Smalltalk, it has garbage collection, a feature
that frees the programmer from explicitly allocating and de-allocating
memory. And it runs on a Smalltalk-style virtual machine, software
built into your web browser which executes the same standard compiled
Java bytecodes no matter what type of computer you have.
Java development
tools are being rapidly deployed, and are available from such major software
companies as IBM, Microsoft, and Symantec.
In Summary
Object-oriented
programming offers a new and powerful model for writing computer software.
Objects are "black boxes" which send and receive messages. This
approach speeds the development of new programs, and, if properly used,
improves the maintenance, reusability, and modifiability of software.
O-O programming
requires a major shift in thinking by programmers, however. The C++ language
offers an easier transition via C, but it still requires an o-o design
approach in order to make proper use of this technology. Smalltalk offers
a pure o-o environment, with more rapid development time and greater flexibility
and power. Java promises much for Web-enabling o-o programs. |